//
//  WMPhotoCache.m
//  WeightMaster
//
//  Created by sungeo on 15/9/1.
//  Copyright (c) 2015年 buddysoft. All rights reserved.
//

#import "WMPhotoCache.h"
#import "BDFoundation.h"
#import "WMPhoto.h"
#import <EXTScope.h>
#import <TMCache.h>
#import <NSObject+GLPubSub.h>

NSString * const PhotoDownloadedNote = @"PhotoDownloadedNote";

static NSCache * sImageCache = nil;

static NSString * const WMPhotoCacheKey = @"PhotoCacheKey";

@interface WMPhotoCache (){
    NSMutableDictionary * _internalObjects;
    
    BDiCloudManager * _iCloudManager;
    
    NSTimer * _syncingTimer;
}

@end

@implementation WMPhotoCache

+ (instancetype)sharedInstance{
    static WMPhotoCache * sInstance = nil;
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (sInstance == nil) {
            sInstance = [[WMPhotoCache alloc] init];
        }
    });
    
    return sInstance;
}

- (instancetype)init{
    if (self = [super init]) {
        
        // 加载缓存中的对象
        id objects = [[TMDiskCache sharedCache] objectForKey:WMPhotoCacheKey];
        if ([objects isKindOfClass:[NSDictionary class]]) {
            _internalObjects = [((NSDictionary *)objects) mutableCopy];
        }
        
        if (_internalObjects == nil) {
            _internalObjects = [NSMutableDictionary dictionary];
        }
        
        // 图片管理定时器
        _syncingTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(syncingProfileImage:) userInfo:nil repeats:YES];
        
        _iCloudManager = [[BDiCloudManager alloc] init];
        _iCloudManager.delegate = self;
        
        // 初始化图片内存缓存
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            if (sImageCache) {
                sImageCache = [[NSCache alloc] init];
            }
        });

    }
    
    return self;
}

- (void)syncPhotosToDisk{
    [[TMDiskCache sharedCache] setObject:_internalObjects forKey:WMPhotoCacheKey];
}

- (WMPhoto *)photoWithUUID:(NSString *)uuid{
    if (uuid.length == 0) {
        return nil;
    }
    
    return [_internalObjects objectForKey:uuid];
}

- (void)syncingProfileImage:(NSTimer *)timer{
    if (! [BDiCloudManager serviceReady]) {
        return;
    }
    
    if (self.isSyncingToICloud) {
        return;
    }
    
    self.isSyncingToICloud = YES;
    
    // 删除照片优先级最高，上传次之，下载最低
    for (NSString * key in _internalObjects) {
        WMPhoto * photo = _internalObjects[key];
        if (photo.needDelete.boolValue) {
            // 删除照片
            return [self deletePhoto:photo];
            
        }else if(photo.isUploaded.boolValue == NO){
            // 上传照片
            return [self uploadPhoto:photo];
        }
    }
    
    self.isSyncingToICloud = NO;
}

- (void)uploadPhoto:(WMPhoto *)photo{
    CKRecord * record = [photo iCloudRecord];
    
    [_iCloudManager.privateDatabase saveRecord:record completionHandler:^(CKRecord * record, NSError * error){
        if (error == nil) {
            NSLog(@"照片存储到云端成功");
            photo.isUploaded = @(YES);
            [self syncPhotosToDisk];
            
        }else{
            NSLog(@"照片存储到云端失败：%@", error);
        }
        
        self.isSyncingToICloud = NO;
    }];
}

- (void)deletePhoto:(WMPhoto *)photo{
    CKRecordID * recordID = [[CKRecordID alloc] initWithRecordName:photo.UUID];
    
    @weakify(self);
    [_iCloudManager.privateDatabase deleteRecordWithID:recordID completionHandler:^(CKRecordID * recordID, NSError * error){
        @strongify(self);
        if (error == nil) {
            NSLog(@"云端删除照片成功");
            
            // 删除磁盘缓存中的照片
            [photo deleteLocalPhoto];
            
            // 删除内存缓存中的照片
            [self deleteCahceForImageID:photo.UUID];
            
            // 删除对象
            [_internalObjects removeObjectForKey:photo.UUID];
            [self syncPhotosToDisk];
            
        }else{
            NSLog(@"云端删除照片失败: %@", error);
        }
        
        self.isSyncingToICloud = NO;
    }];
}

- (void)downloadPhotoWithUUID:(NSString *)uuid{
    static NSCache * sDownloadQueue = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (sDownloadQueue == nil) {
            sDownloadQueue = [[NSCache alloc] init];
        }
    });
    
    if ([sDownloadQueue objectForKey:uuid] != nil) {
        NSLog(@"照片正在下载中，不能重复下载");
        return;
    }
    
    // 添加下载任务到缓存
    [sDownloadQueue setObject:@(YES) forKey:uuid];
    
    CKRecordID * recordID = [[CKRecordID alloc] initWithRecordName:uuid];
    
    @weakify(self);
    [_iCloudManager.privateDatabase fetchRecordWithID:recordID completionHandler:^(CKRecord * record, NSError * error){
        @strongify(self);
        
        if (record == nil) {
            NSLog(@"照片下载失败：%@", error);
        }else{
            WMPhoto * photo = [self photoWithUUID:uuid];
            UIImage * image = [photo updateImageWithCKRecord:record];
            if (image) {
                
                // 添加到内存照片缓存
                [sImageCache setObject:image forKey:uuid];
                [self publish:PhotoDownloadedNote data:uuid];
                NSLog(@"下载照片成功：UUID %@", uuid);
                
            }else{
                NSLog(@"下载照片信息中没有图片数据");
            }
        }
        
        // 将下载任务从缓存中清除
        [sDownloadQueue removeObjectForKey:uuid];

    }];
}

- (BOOL)addImage:(UIImage *)image withUUID:(NSString *)uuid{
    WMPhoto * photo = [self photoWithUUID:uuid];
    if (photo) {
        return NO;
    }
    
    photo = [[WMPhoto alloc] init];
    photo.UUID = uuid;
    // 赋值时会自动缓存到本地文件系统
    photo.image = image;
    photo.isDownloaded = @(YES);
    photo.isUploaded = @(NO);
    
    [_internalObjects setObject:photo forKey:uuid];
    
    [self syncPhotosToDisk];
    
    return YES;
}

- (void)deleteCahceForImageID:(NSString *)uuid{
    if (sImageCache != nil) {
        [sImageCache removeObjectForKey:uuid];
    }
}

- (UIImage *)imageWithUUID:(NSString *)uuid{

    // 尝试从内存缓存加载
    UIImage * image = [sImageCache objectForKey:uuid];
    if (image) {
        return image;
    }else{
        // 从磁盘加载
        NSURL * localURL = [WMPhoto localImageURLForUUID:uuid];
        if ([[NSFileManager defaultManager] fileExistsAtPath:localURL.path]) {
            image = [UIImage imageWithContentsOfFile:localURL.path];
            [sImageCache setObject:image forKey:uuid]; // 添加到内存缓存
            return image;
        }else{
            
            // 从云端查询
            [self downloadPhotoWithUUID:uuid];
            return nil;
        }
    }
}

- (void)deleteImageWithUUID:(NSString *)uuid{
    WMPhoto * photo = [self photoWithUUID:uuid];
    if (photo) {
        photo.needDelete = @(YES);
        NSLog(@"需要删除图片：%@", uuid);
    }
}

@end
